import 'dart:io';

import 'package:demo/http/params_interceptor.dart';
import 'package:demo/http/request.dart';
import 'package:dio/adapter.dart';
import 'package:dio/dio.dart';
import 'api_response.dart';
import 'app_exceptions.dart';
import 'header_interceptor.dart';
import 'log_interceptor.dart';
import 'sign_interceptor.dart';

typedef OnCacheCallback<T> = void Function(T t);

class Https {
  ///超时时间
  static const int connectTimeout = 10000;
  static const int receiveTimeout = 10000;

  static final Https instance = Https._internal();

  factory Https() => instance;

  Dio dio = Dio();

  Https._internal() {
    dio.options
      ..baseUrl = "https://api.dailyworkout.cn/"
      ..connectTimeout = connectTimeout
      ..receiveTimeout = receiveTimeout
      ..validateStatus = (int? status) {
        return status != null && status > 0;
      };
    dio.interceptors.add(HeaderInterceptor());
    dio.interceptors.add(ParamsInterceptor());
    dio.interceptors.add(SignInterceptor());
    dio.interceptors.add(LoggerInterceptor(requestBody: true));
  }

  Request<T> request<T>(
    String path, {
    Map<String, dynamic>? params,
    Options? options,
  }) {
    return Request<T>(dio, path, params: params, options: options);
  }

  /// restful get 操作
  @Deprecated("已废弃,请使用新的api request()")
  Future<ApiResponse<T>> get<T>(
    String path, {
    Map<String, dynamic>? params,
    Options? options,
  }) async {
    Request<T> request = Request<T>(dio, path, params: params, options: options);
    return request.get();
  }

  /// restful post 操作
  @Deprecated("已废弃,请使用新的api request()")
  Future<ApiResponse<T>> post<T>(
    String path, {
    Map<String, dynamic>? params,
    Options? options,
  }) async {
    Request<T> request = Request<T>(dio, path, params: params, options: options);
    return request.post();
  }

  Future<ApiResponse<String>> download(
    String path,
    String savePath, {
    Map<String, dynamic>? queryParameters,
    ProgressCallback? onReceiveProgress,
    Options? options,
    int receivedBytes = 0,
  }) async {
    try {
      var targetOptions = options ?? Options();
      var response = await dio.download(path, savePath,
          queryParameters: queryParameters,
          onReceiveProgress: onReceiveProgress,
          options: targetOptions
            ..receiveTimeout = 0
            ..headers = {HttpHeaders.rangeHeader: 'bytes=$receivedBytes-'});
      if (response.statusCode == 200) {
        return ApiResponse.success(savePath);
      } else {
        return ApiResponse.error(AppException.errResponse(response));
      }
    } catch (e) {
      return ApiResponse.error(AppException.create(e is DioError ? e.error : e));
    }
  }
}
